using System;
using System.IO;
using System.Windows.Forms;

using Org.BouncyCastle.Asn1;
using iSonar.Lib.Utils;
using iSonar.iCarus.Gui.Dialogs;
using iSonar.iCarus.Interfaces;

namespace iSonar.iCarus.Gui.Controls {
  public partial class Asn1ViewCtrl : UserControl {
    public Asn1ViewCtrl(IApplication app) {
      m_application = app;
      InitializeComponent();
    }

    public void ExpandTree(bool expand) {
      if (true == expand) {
        treeView_ASN1.ExpandAll();
      } else {
        treeView_ASN1.CollapseAll();
      }
    }

    public void SetContent(Stream s) {
      try {
        treeView_ASN1.Nodes.Clear();
        TreeNode _root = treeView_ASN1.Nodes.Add("ASN.1");
        Asn1InputStream _stream = new Asn1InputStream(s);
        Asn1Object _obj;
        for (; null != (_obj = _stream.ReadObject()); ) {
          AddToTree(_root, _obj);
        }
      } catch (Exception ex) {
        AppError _err = new AppError(ex);
        _err.ShowDialog(this);
      }
    }

    private void AddToTree(TreeNode node, Asn1Object obj) {
      TreeNode _newNode = null;
      if (obj is Asn1Sequence) {
        Asn1Sequence _seq = obj as Asn1Sequence;
        _newNode = node.Nodes.Add("Seqence");
        foreach (Asn1Object _o in _seq) {
          AddToTree(_newNode, _o);
        }
      } else if (obj is Asn1Set) {
        Asn1Set _set = obj as Asn1Set;
        _newNode = node.Nodes.Add("Set");
        foreach (Asn1Object _o in _set) {
          AddToTree(_newNode, _o);
        }
      } else if (obj is Asn1OctetString) {
        _newNode = node.Nodes.Add("Octet string");
      } else if (obj is DerUtcTime) {
        _newNode = node.Nodes.Add("UTC Time: " + obj.ToString());
      } else if (obj is IAsn1String) {
        _newNode = node.Nodes.Add("String: " + obj.ToString());
      } else if (obj is Asn1Null) {
        _newNode = node.Nodes.Add("Null");
      } else if (obj is DerObjectIdentifier) {
        DerObjectIdentifier _oid = (DerObjectIdentifier)obj;
        _newNode = node.Nodes.Add("ObjectIdentifier: " + _oid.ToString());
      } else if (obj is DerInteger) {
        Byte[] _tmp = ((DerInteger)obj).Value.ToByteArray();
        _newNode = node.Nodes.Add("Integer: " + HexEncoder.Encode(_tmp, 0, _tmp.Length));
      } else if (obj is DerTaggedObject) {
        DerTaggedObject _tmp = (DerTaggedObject)obj;
        _newNode = node.Nodes.Add("TaggedObject: " + _tmp.TagNo.ToString());
        if (!_tmp.IsEmpty()) {
          AddToTree(_newNode, _tmp.GetObject());
        }
      } else if (obj is DerUnknownTag) {
        String _s = "Unknown: " + ((int)((DerUnknownTag)obj).Tag).ToString("X");
        _newNode = node.Nodes.Add(_s);
      } else {
        _newNode = node.Nodes.Add("[" + obj.GetType().ToString() + "] " + obj.ToString());
      }
      if (null != _newNode) {
        _newNode.Tag = obj;
      }
    }

    private void treeView_ASN1_AfterSelect(object sender, TreeViewEventArgs e) {
      TreeView _tree = sender as TreeView;
      if ((null == _tree) || (null == _tree.SelectedNode)) {
        return;
      }
      Asn1Object _obj = _tree.SelectedNode.Tag as Asn1Object;
      if (null == _obj) {
        return;
      }
      if (null != m_application) {
        m_application.ShowItemDetails(new iSonar.iCarus.Core.DataTypes.Binary(_obj.GetEncoded()));
      }
    }

    private IApplication m_application;

    private void expandToolStripMenuItem_Click(object sender, EventArgs e) {
      TreeNode node = treeView_ASN1.SelectedNode;
      if (null != node) {
        node.ExpandAll();
      }
    }

    private void collapseAllToolStripMenuItem_Click(object sender, EventArgs e) {
      TreeNode node = treeView_ASN1.SelectedNode;
      if (null != node) {
        node.Collapse(false);
      }
    }

    private void detailsToolStripMenuItem_Click(object sender, EventArgs e) {
      TreeNode node = treeView_ASN1.SelectedNode;
      if (null != node) {
        m_application.ShowItemDetails(null);
      }
    }
  }
}